<?php

// 退款查询通知控制器

namespace app\api\controller;

use app\api\controller\Base;
use think\facade\Cache;
use think\facade\Log;
use think\Db;

class RefundQuery extends Base
{

    /**
     * 退款查询通知
     */
    public function query()
    {
        try {
            // 只允许命令行访问
            if (PHP_SAPI != 'cli') {
                return ['code' => 999, 'msg' => '404'];
            }

            // 设置至少间隔多少秒处理一次
            $notice_time = 15;

            // 退款公司配置
            $all_child_company = Db::name('payment_pay_company')
                ->where([])
                ->column('*', 'name');

            Db::name('payment_order_refund')
                ->where('status', '=', 1)
                ->chunk(10, function ($all) use ($notice_time, $all_child_company) {
                    foreach ($all as $single) {

                        // 处理规则
                        if ($single['update_time'] + $notice_time < time()) {
                            sleep(1);
                            $redis = Cache::store('redis');

                            // 可能会在一秒中多次通知相同订单，用redis处理。
                            $order_notify_key = 'order_notify_' . $single['order_id'];
                            $order_notify = $redis->has($order_notify_key);
                            if ($order_notify) {
                                //payment_error_log(910001, $single, '多次通知:在一秒中多次通知相同订单');
                                unset($single);
                                continue;
                            } else {
                                $redis->set($order_notify_key, 1, 5);
                            }

                            // 订单状态
                            if (isset($order_status)) {
                                unset($order_status);
                            }

                            if (!isset($all_child_company[$single['child_company']])) {
                                payment_error_log(910002, $single);
                                continue;
                            }
                            $child_company_config = $all_child_company[$single['child_company']];
                            // 退款公司关闭定时自动查询
                            if ($child_company_config['refund_open'] == 0) {
                                continue;
                            }

                            $payment_company = $single['company'] . 'Verify';
                            $order_id = $single['order_id'];
                            if (in_array($single['company'], ['abcdefg'])) {
                                $order_id = $single['other_order_id'];
                            }

                            // 实例化退款订单模型
                            $card_paid_obj = new \app\api\model\PaymentOrderRefund();
                            $resdata = $card_paid_obj->$payment_company($order_id, $child_company_config, $single, false, true);

                            $return_param = $resdata['return_param'];
                            $resarray = json_decode($return_param, true);

                            // 支付宝退款
                            if ($single['company'] == 'zfbpay') {
                                if (isset($resarray['alipay_trade_fastpay_refund_query_response']['code'])) {
                                    // 成功
                                    if ($resarray['alipay_trade_fastpay_refund_query_response']['code'] == 10000) {
                                        $order_status = 2;
                                    }
                                    // 失败
                                    if ($resarray['alipay_trade_fastpay_refund_query_response']['code'] > 10000) {
                                        $order_status = 3;
                                    }
                                }
                            }

                            // 微信退款
                            if ($single['company'] == 'wxpay') {
                                if (isset($resarray['status'])) {
                                    // 成功
                                    if ($resarray['status'] == 'SUCCESS') {
                                        $order_status = 2;
                                    }
                                }
                                if (isset($resarray['code'])) {
                                    // 失败
                                    if ($resarray['code'] == 'RESOURCE_NOT_EXISTS') {
                                        $order_status = 3;
                                    }
                                }
                            }

                            // 传化退款
                            if ($single['company'] == 'chuanhua') {
                                if (isset($resarray['data'])) {
                                    // 成功
                                    $chuanhua_data = json_decode($resarray['data'], true);
                                    if (isset($chuanhua_data['status']) && $chuanhua_data['status'] == '成功') {
                                        $order_status = 2;
                                    }
                                }
                                if (isset($resarray['biz_code'])) {
                                    // 失败
                                    if ($resarray['biz_code'] == 'GPBIZ_030001') {
                                        $order_status = 3;
                                    }
                                }
                            }

                            if (isset($order_status)) {

                                try {
                                    $update_data = Db::name('payment_order_refund')
                                        ->where(['order_id' => $single['order_id'], 'status' => 1])
                                        ->update(['status' => $order_status, 'update_time' => time()]);
                                } catch (\Exception $e) {
                                    payment_error_log(910003, $single, $e->getMessage());
                                    continue;
                                }

                                // 更新退款订单表状态失败
                                if (!$update_data) {
                                    payment_error_log(910004, $single);
                                    continue;
                                }

                                // 失败：退款金额退回
                                if ($order_status == 3) {
                                    try {
                                        Db::name('payment_cash')
                                            ->where(['merchant_id' => $single['merchant_id']])
                                            ->inc('cash', $single['deduct_cash'])
                                            ->dec('refund_sum_cash', $single['deduct_cash'])
                                            ->dec('refund_count', 1)
                                            ->update(['update_time' => time()]);
                                    } catch (\Exception $e) {
                                        payment_error_log(910005, $single, $e->getMessage());
                                    }
                                }
                                // 成功：处理商户等配置
                                if ($order_status == 2) {

                                    // 指定退款公司不执行
                                    if (!in_array($single['company'], ['zfb'])) {
                                    }
                                }

                                // 把退款信息通知给商户
                                $merchant_create_param = json_decode($single['create_param'], true);
                                // 商户开启通知
                                if ($merchant_create_param['notify_open'] == 1) {
                                    $notify_url = $merchant_create_param['notify_url'];
                                    $notify_data['code'] = 10000;                                                    // 成功状态码
                                    $notify_data['merchant_id'] = $single['merchant_id'];                            // 商户号
                                    $notify_data['merchant_order_id'] = $single['merchant_order_id'];                // 商户退款订单号
                                    $notify_data['old_merchant_order_id'] = $single['old_merchant_order_id'];        // 原商户订单号
                                    $notify_data['order_id'] = $single['order_id'];                                  // 平台订单号
                                    $notify_data['app_id'] = $single['app_id'];                                      // 应用id
                                    $notify_data['cash'] = $single['cash'] / 100;                                    // 退款现金   
                                    $notify_data['deduct_cash'] = $single['deduct_cash'] / 100;                      // 扣除金额     
                                    $notify_data['old_cash'] = $single['old_cash'] / 100;                            // 原订单金额    
                                    $notify_data['mode'] = $single['mode'];                                          // 退款方法：0自动，1手动
                                    $notify_data['trade_type'] = $single['trade_type'];                              // 交易类型：比如充值、退款                                  
                                    $notify_data['body'] = $single['body'];                                          // 退款说明
                                    $notify_data['time'] = time();                                                   // 更新时间
                                    $notify_data['extra'] = $merchant_create_param['extra'];                         // 商户自定义备注
                                    // 订单状态：1:处理中 2:成功 3:失败 4:异常
                                    $notify_data['status'] = $order_status;
                                    $notify_data['sign'] = md5('merchant_id=' . $notify_data['merchant_id'] . '&merchant_order_id=' . $notify_data['merchant_order_id'] . '&old_merchant_order_id=' . $notify_data['old_merchant_order_id'] . '&order_id=' . $notify_data['order_id'] . '&cash=' . $notify_data['cash'] . '&status=' . $notify_data['status'] . '&time=' . $notify_data['time'] . '&key=' . $merchant_create_param['key']);

                                    $resdata = go_curl($notify_url, $notify_data, 'get', 12);
                                    if (stripos($resdata, 'success') === false) {
                                        // 通知失败,准备多次通知
                                        $url_param = http_build_query($notify_data);
                                        $url = strpos($notify_url, '?') !== false ? $notify_url . '&' . $url_param : $notify_url . '?' . $url_param;

                                        $notify_array = [
                                            'order_id' => $single['order_id'],
                                            'merchant_id' => $single['merchant_id'],
                                            'merchant_order_id' => $single['merchant_order_id'],
                                            'other_order_id' => $single['other_order_id'],
                                            'app_id' => $single['app_id'],
                                            'cash' => $single['cash'],
                                            'type' => 0,
                                            'trade_type' => $single['trade_type'],
                                            'status' => 0,
                                            'manual' => 0,
                                            'count' => 0,
                                            'create_time' => $single['create_time'],
                                            'update_time' => time(),
                                            'url' => $url,
                                            'remark' => substr($resdata, 0, 60000),
                                        ];
                                        // 插入多次通知数据库
                                        try {
                                            Db::name('payment_order_notify')->insert($notify_array);
                                        } catch (\Exception $e) {
                                            payment_error_log(910006, $notify_array, $e->getMessage());
                                        }

                                        Log::record("退款通知商户号{$single['merchant_id']}失败记录：" . $single['order_id'] . '——' . '0', 'log');
                                        Log::record('退款通知URL参数：' . $url, 'log');
                                        Log::record('退款通知返回内容：' . $resdata, 'log');
                                    }
                                }

                                unset($order_status);
                            }
                        }

                        unset($single);
                    }
                }, 'update_time', 'asc');
        } catch (\Exception $e) {
            payment_error_log(910000, $e->getMessage());
            return ['code' => 999, 'msg' => '404'];
        }
    }
}
